home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / amoeba.pro < prev    next >
Text File  |  1997-07-08  |  7KB  |  197 lines

  1. ; $Id: amoeba.pro,v 1.4 1997/04/11 19:57:21 dave Exp $
  2. ; Copyright (c) 1996-1997, Research Systems, Inc.  All rights reserved.
  3. ;    Unauthorized reproduction prohibited.
  4.  
  5.  
  6. Function amotry, p, y, psum, func, ihi, fac
  7. ; Extrapolates by a factor fac through the face of the simplex, across
  8. ; from the high point, tries it and replaces the high point if the new
  9. ; point is better.
  10.  
  11.   fac1 = (1.0 - fac) / n_elements(psum)
  12.   fac2 = fac1  - fac
  13.   ptry = psum * fac1 - p[*,ihi] * fac2
  14.   ytry = call_function(func, ptry)  ;Eval fcn at trial point
  15.   if ytry lt y[ihi] then begin    ;If its better than highest, replace highest
  16.     y[ihi] = ytry
  17.     psum = psum + ptry - p[*,ihi]
  18.     p[0,ihi] = ptry
  19.     endif
  20.   return, ytry
  21. end
  22.  
  23.  
  24. Function Amoeba, ftol, FUNCTION_NAME=func, FUNCTION_VALUE=y, $
  25.     NCALLS = ncalls, NMAX = nmax, P0 = p0, SCALE=scale, SIMPLEX=p
  26. ; The Numerical Recipes procedure Amoeba, with some embellishments.
  27. ;
  28. ; Reference: Numerical Recipes, 2nd Edition, Page 411.
  29. ;  P = fltarr(ndim, ndim+1)
  30. ;+
  31. ; NAME:
  32. ;    AMOEBA
  33. ;
  34. ; PURPOSE:
  35. ;    Multidimensional minimization of a function FUNC(X), where
  36. ;    X is an N-dimensional vector, using the downhill simplex
  37. ;    method of Nelder and Mead, 1965, Computer Journal, Vol 7, pp 308-313.
  38. ;
  39. ;    This routine is based on the AMOEBA routine, Numerical
  40. ;    Recipes in C: The Art of Scientific Computing (Second Edition), Page
  41. ;    411, and is used by permission.
  42. ;
  43. ; CATEGORY:
  44. ;    Function minimization/maximization. Simplex method.
  45. ;
  46. ; CALLING SEQUENCE:
  47. ;    Result = AMOEBA(Ftol, ....)
  48. ; INPUTS:
  49. ;    FTOL:  the fractional tolerance to be achieved in the function
  50. ;    value.  e.g. the fractional decrease in the function value in the
  51. ;    terminating step.  This should never be less than the
  52. ;    machine's single or double precision.
  53. ; KEYWORD PARAMETERS:
  54. ;    FUNCTION_NAME: a string containing the name of the function to
  55. ;    be minimized.  If omitted, the function FUNC is minimized.
  56. ;    This function must accept an Ndim vector as its only parameter and
  57. ;    return a scalar single or double precision floating point value as its
  58. ;    result. 
  59. ;    FUNCTION_VALUE: (output) on exit, an Ndim+1 element vector
  60. ;    containing the function values at the simplex points.  The first
  61. ;    element contains the function minimum. 
  62. ;    NCALLS: (output) the of times the function was evaluated. 
  63. ;    NMAX: the maximum number of function evaluations allowed
  64. ;    before terminating.  Default = 5000.
  65. ;    P0: Initial starting point, an Ndim element vector.  The starting
  66. ;    point must be specified using either the keyword SIMPLEX, or P0 and
  67. ;    SCALE.  P0 may be either single or double precision floating.
  68. ;    For example, in a 3-dimensional problem, if the initial guess
  69. ;    is the point [0,0,0], and it is known that the function's
  70. ;    minimum value occurs in the interval: -10 <
  71. ;    X(0) < 10, -100 < X(1) < 100, -200 < X(2) < 200, specify: P0=[0,0,0],
  72. ;    SCALE=[10, 100, 200]. 
  73. ;    SCALE: a scalar or Ndim element vector contaiing the problem's
  74. ;    characteristic length scale for each dimension.
  75. ;    SCALE is used with P0 to form an initial (Ndim+1) point simplex.
  76. ;    If all dimensions have the same    scale, specify a scalar.
  77. ;    SIMPLEX: (output and/or optional input) On input, if P0 and SCALE
  78. ;    are not set, SIMPLEX contains the Ndim+1 vertices, each of
  79. ;    Ndim elements, of starting simplex, in either single or double
  80. ;    precision floating point, in an (Ndim, Ndim+1) array. On output,
  81. ;    SIMPLEX contains the simplex, of dimensions (Ndim, Ndim+1), enclosing
  82. ;    the function minimum.  The first point, Simplex(*,0), corresponds to
  83. ;    the function's minimum.
  84. ;
  85. ; OUTPUTS:
  86. ;   Result: If the minimum is found, an Ndim vector, corresponding to
  87. ;    the Function's minimum value is returned.  If a function minimum
  88. ;    within the given tolerance, is NOT found in the given number of
  89. ;    evaluations, a scalar value of -1 is returned.
  90. ;
  91. ; COMMON BLOCKS:
  92. ;    None.
  93. ;
  94. ; SIDE EFFECTS:
  95. ;    None.
  96. ;
  97. ; PROCEDURE:
  98. ;    This procedure implements the Simplex method, described in
  99. ;    Numerical Recipes, Section 10.4.  See also the POWELL procedure.
  100. ;
  101. ;    Advantages:  requires only function evaluations, not
  102. ;    derivatives, may be more reliable than the POWELL method.
  103. ;    Disadvantages: not as efficient as Powell's method, and usually
  104. ;    requires more function evaluations.
  105. ;
  106. ;    Results are performed in the mode (single or double precision)
  107. ;    returned by the user-supplied function.  The mode of the inputs P0,
  108. ;    SCALE, or SIMPLEX, should match that returned by the function. The
  109. ;    mode of the input vector supplied to the user-written function, is
  110. ;    determined by P0, SCALE, or SIMPLEX.
  111. ;
  112. ; EXAMPLE:
  113. ;    Use Amoeba to find the slope and intercept of a straight line fitting
  114. ;    a given set of points minimizing the maximum error:
  115. ;
  116. ;    The function to be minimized returns the maximum error,
  117. ;    given p(0) = intercept, and p(1) = slope:
  118. ; FUNCTION FUNC, p
  119. ; COMMON FUNC_XY, x, y
  120. ; RETURN, MAX(ABS(y - (p(0) + p(1) * x)))
  121. ; END
  122. ;
  123. ;    Put the data points into a common block so they are accessible to the
  124. ;    function: 
  125. ; COMMON FUNC_XY, x, y
  126. ;    Define the data points:
  127. ;   x = findgen(17)*5
  128. ;   y = [ 12.0,  24.3,  39.6,  51.0,  66.5,  78.4,  92.7, 107.8, 120.0, $
  129. ;        135.5, 147.5, 161.0, 175.4, 187.4, 202.5, 215.4, 229.9]
  130. ;
  131. ;    Call the function.  Fractional tolerance = 1 part in 10^5, 
  132. ;    Initial guess = [0,0], and the minimum should be found within
  133. ;    a distance of 100 of that point: 
  134. ;   r = AMOEBA(1.0e-5, SCALE=1.0e2, P0 = [0, 0], FUNCTION_VALUE=fval)
  135. ;
  136. ;    Check for convergence:
  137. ;   if n_elements(r) eq 1 then message,'AMOEBA failed to converge'
  138. ;    Print results.
  139. ;   print, 'Intercept, Slope:', r, 'Function value (max error): ', fval(0)
  140. ;Intercept, Slope:      11.4100      2.72800
  141. ;Function value:       1.33000
  142. ;
  143. ; MODIFICATION HISTORY:
  144. ;    DMS, May, 1996.    Written.
  145. ;-
  146.  
  147. if keyword_set(scale) then begin  ;If set, then p0 is initial starting pnt
  148.    ndim = n_elements(p0)
  149.    p = p0 # replicate(1.0, ndim+1)
  150.    for i=0, ndim-1 do p[i,i+1] = p0[i] + scale[i < (n_elements(scale)-1)]
  151. endif
  152.  
  153. s = size(p)
  154. if s[0] ne 2 then message, 'Either (SCALE,P0) or SIMPLEX must be initialized'
  155. ndim = s[1]            ;Dimensionality of simplex
  156. mpts = ndim+1            ;# of points in simplex
  157. if n_elements(func) eq 0 then func = 'FUNC'
  158. if n_elements(nmax) eq 0 then nmax = 5000L
  159.  
  160. y = replicate(call_function(func, p[*,0]), mpts)  ;Init Y to proper type
  161. for i=1, ndim do y[i] = call_function(func, p[*,i]) ;Fill in rest of the vals
  162. ncalls = 0L
  163. psum = total(p,2)
  164.  
  165. while ncalls le nmax do begin        ;Each iteration
  166.   s = sort(y)
  167.   ilo = s[0]        ;Lowest point
  168.   ihi = s[ndim]        ;Highest point
  169.   inhi = s[ndim-1]    ;Next highest point
  170.   rtol = 2.0 * abs(y[ihi]-y[ilo])/(abs(y[ihi])+abs(y[ilo]))
  171.  
  172.   if rtol lt ftol then begin        ;Done?
  173.     t = y[0] & y[0] = y[ilo] & y[ilo] = t    ;Sort so fcn min is 0th elem
  174.     t = p[*,ilo] & p[*,ilo] = p[*,0] & p[*,0] = t
  175.     return, t        ;params for fcn min
  176.     endif
  177.  
  178.   ncalls = ncalls + 2
  179.   ytry = amotry(p, y, psum, func, ihi, -1.0)
  180.   if ytry le y[ilo] then ytry = amotry(p,y,psum, func, ihi, 2.0) $
  181.   else if ytry ge y[inhi] then begin
  182.     ysave = y[ihi]
  183.     ytry = amotry(p,y,psum,func, ihi, 0.5)
  184.     if ytry ge ysave then begin
  185.     for i=0, ndim do if i ne ilo then begin
  186.       psum = 0.5 * (p[*,i] + p[*,ilo])
  187.       p[*,i] = psum
  188.       y[i] = call_function(func, psum)
  189.       endif
  190.     ncalls = ncalls + ndim
  191.     psum = total(p,2)
  192.     endif        ;ytry ge ysave
  193.     endif else ncalls = ncalls  - 1
  194.   endwhile
  195.   return, -1        ;Here, the function failed to converge.
  196. end
  197.